package com.library.verification.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.library.verification.R;

import java.util.Random;

/**
 * 图片验证码
 */
public class CheckView extends View {
    private Context mContext;
    private String mCheckCode = null;
    private Paint mTempPaint = new Paint();
    private int mPointNum;
    private int mLineNum;
    private int mTextLength;
    private float mTextSize;
    private int mTextColor;
    private int mBgColor;
    private boolean isRefresh;
    private CheckCodeAttrs checkCodeAttrs;

    // 验证码
    public CheckView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckView);
        try {
            // 获取随机点的个数
            mPointNum = a.getInteger(R.styleable.CheckView_check_point_num, 0);
            // 获取随机线的条数
            mLineNum = a.getInteger(R.styleable.CheckView_check_line_num, 0);
            // 获取验证码长度
            mTextLength = a.getInteger(R.styleable.CheckView_check_text_length, 4);
            // 获取验证码字体大小
            mTextSize = a.getDimension(R.styleable.CheckView_check_text_size, 30);
            // 获取验证码字体颜色
            mTextColor = a.getColor(R.styleable.CheckView_check_text_color, 0XFFFFFFFF);
            // 获取背景颜色
            mBgColor = a.getColor(R.styleable.CheckView_check_bg_color, 0XFFFFFFFF);

        } catch (Exception e) {

        } finally {
            if (a != null) {
                a.recycle();
            }
        }


        mTempPaint.setAntiAlias(true);
        mTempPaint.setTextSize(mTextSize);
        mTempPaint.setStrokeWidth(3);
        mTempPaint.setColor(mTextColor);
        mCheckCode = initCheckCode();
    }

    /**
     * 初始化验证码
     */
    private String initCheckCode() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mTextLength; i++) {
//            int temp = (int) (Math.random() * 10);
            sb.append("A");
        }
        return sb.toString();
    }

    public void onDraw(Canvas canvas) {

        final int height = getHeight();
        // 获得CheckView控件的高度
        final int width = getWidth();
        if (isRefresh) {
            checkCodeAttrs = new CheckCodeAttrs();
            checkCodeAttrs.cirPos = makePoints(height, width);
            checkCodeAttrs.linePos = makeLines(height, width);
            checkCodeAttrs.codeColors = makeCodeFontColors();
            isRefresh = false;
        }
        canvas.drawColor(mBgColor);
        // 获得CheckView控件的宽度
        int dx = width / mTextLength / 2;

        char[] checkNum = mCheckCode.toCharArray();
        for (int i = 0; i < mTextLength; i++) {
            int color;
            // 绘制验证控件上的文本
            if (checkCodeAttrs != null) {
                color = checkCodeAttrs.codeColors[i];
            } else {
                color = getCodeFontColor();
            }
            mTempPaint.setColor(color);
            canvas.drawText("" + checkNum[i], dx, getPositon(height), mTempPaint);
            dx += width / (mTextLength + 1);
        }
        int[] line = null;
        for (int i = 0; i < mLineNum; i++) {
            // 划线
            if (checkCodeAttrs != null) {
                line = checkCodeAttrs.linePos[i];
            } else {
                line = getLine(height, width);
            }

            mTempPaint.setColor(mTextColor);
            canvas.drawLine(line[0], line[1], line[2], line[3], mTempPaint);
        }
        // 绘制小圆点
        int[] point = null;
        for (int i = 0; i < mPointNum; i++) {
            mTempPaint.setColor(mTextColor);
            // 画点
            if (checkCodeAttrs != null) {
                point = checkCodeAttrs.cirPos[i];
            } else {
                point = getPoint(height, width);
            }

            canvas.drawCircle(point[0], point[1], 1, mTempPaint);
        }


    }

    class CheckCodeAttrs {
        String code;
        int[] codeColors;
        int[][] linePos;
        int[][] cirPos;
    }

    /**
     * 测量字体大小
     *
     * @param str
     * @return
     */
    private int[] measureCodeFontSize(String str) {
        Rect rect = new Rect();
        mTempPaint.getTextBounds(str, 0, str.length(), rect);
        int w = rect.width();
        int h = rect.height();
        return new int[]{w, h};
    }

    private float meausureCodeFontPos(String str) {
        if (TextUtils.isEmpty(str)) {
            return 0;
        }

        Paint.FontMetrics metrics = mTempPaint.getFontMetrics();
        //metrics.ascent为负数
        float dy = -(metrics.descent + metrics.ascent) / 2;
        return dy;
    }

    private int[] makeCodeFontColors() {
        int ranColors[] = new int[mTextLength];
        for (int i = 0; i < ranColors.length; i++) {
            ranColors[i] = getCodeFontColor();
        }
        return ranColors;
    }

    private int getCodeFontColor() {
        int ranColor = 0;
        do {
            Random myRandom = new Random();
            ranColor = 0xff000000 | myRandom.nextInt(0x00ffffff);
        } while (ranColor == mBgColor);

        return ranColor;
    }

    private void invaliChenkCode() {
        invalidate();
    }

    public String getCheckCode() {
        return mCheckCode;
    }

    public boolean verification(String code) {
        if (TextUtils.isEmpty(code) || TextUtils.isEmpty(mCheckCode)) {
            return false;
        }
        code = code.toUpperCase();
        if (code.equals(mCheckCode.toUpperCase())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据验证码生成器产生验证码
     *
     * @param checkCodeGenerator
     */
    public void makeCheckCode(ICheckCode checkCodeGenerator) {
        if (checkCodeGenerator != null) {
            String checkCode = checkCodeGenerator.makeCheckCode(mTextLength);
            if (!TextUtils.isEmpty(checkCode)) {
                mCheckCode = checkCode;
            }

        }
        isRefresh = true;
        invaliChenkCode();
    }


    /**
     * 计算验证码的绘制y点位置
     *
     * @param height 传入CheckView的高度值
     * @return
     */
    public float getPositon(int height) {


        float tempPositoin = 0;
//        int valueRange = height - measureCodeFontSize(mCheckCode)[1];
//        if (valueRange > 0) {
//            tempPositoin = valueRange * 2;
//        }

        tempPositoin = height / 2 + meausureCodeFontPos(mCheckCode);
        return tempPositoin;
    }

    private int[][] makeLines(int height, int width) {
        int[][] lines = new int[mLineNum][];
        for (int i = 0; i < mLineNum; i++) {
            lines[i] = getLine(height, width);
        }
        return lines;
    }

    private int[][] makePoints(int height, int width) {
        int[][] pos = new int[mPointNum][];
        for (int i = 0; i < mPointNum; i++) {
            pos[i] = getPoint(height, width);
        }
        return pos;
    }

    /**
     * 随机产生划线的起始点坐标和结束点坐标
     *
     * @param height 传入CheckView的高度值
     * @param width  传入CheckView的宽度值
     * @return 起始点坐标和结束点坐标
     */
    public static int[] getLine(int height, int width) {
        int[] tempCheckNum = {0, 0, 0, 0};
        for (int i = 0; i < 4; i += 2) {
            tempCheckNum[i] = (int) (Math.random() * width);
            tempCheckNum[i + 1] = (int) (Math.random() * height);
        }
        return tempCheckNum;
    }

    /**
     * 随机产生点的圆心点坐标
     *
     * @param height 传入CheckView的高度值
     * @param width  传入CheckView的宽度值
     * @return
     */
    public static int[] getPoint(int height, int width) {
        int[] tempCheckNum = {0, 0, 0, 0};
        tempCheckNum[0] = (int) (Math.random() * width);
        tempCheckNum[1] = (int) (Math.random() * height);
        return tempCheckNum;
    }
}
